'use client';

import { useContext, useEffect, useRef, useState } from 'react';
import type {
  IAssignRoleBody,
  IPagination,
  IQueryParams,
  IRole,
  IUnAssignRoleBody,
  IUser,
} from '@/interfaces';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  assignRole,
  queryAllUser,
  queryRoleUsersById,
  unAssignRole,
} from '@/services/api';
import useToast from '@/hooks/useToast';
import type { TBody } from '@/types';
import Alert from '@/app/[locale]/alert/alert';
import { RoleAdminContext } from '@/contexts/admin/auth/role';
import AlertLoad from '@/app/[locale]/alert/load';
import { type QueryKey } from '@tanstack/query-core';

export default function UserRoleAdminPage(this: any) {
  const context = useContext(RoleAdminContext);
  const updateModalRef = useRef<HTMLDivElement>(null);
  const [type, setType] = useState({
    list: true,
  });

  useEffect(() => {
    onClickOpenModal();
  }, []);

  function onClickMenu(item: 'list') {
    const newType = {
      list: false,
    };

    newType[item] = true;
    setType(newType);
  }

  function onClickOpenModal() {
    getUpdateModal().show();
  }

  function onClickCloseModal() {
    if (typeof context.setUpdateUserItem === 'function') {
      context.setUpdateUserItem(undefined);
    }
    getUpdateModal().hide();
  }

  function getUpdateModal() {
    const current = updateModalRef.current;
    if (!current) {
      throw '更新元素不存在';
    }

    return window.bootstrap.Modal.getOrCreateInstance(current);
  }

  return (
    <div ref={updateModalRef} className="modal fade" data-bs-backdrop="static">
      <div className="modal-dialog modal-xl modal-dialog-scrollable">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title">
              {context.updateItem
                ? `${context.updateItem.name} (${context.updateItem.id})`
                : '更新用户'}
            </h5>
            <button
              onClick={onClickCloseModal}
              type="button"
              className="btn-close"
              aria-label="Close"
            ></button>
          </div>
          <div className="modal-body">
            <div className="row">
              <div className="col-auto">
                <div className="list-group list-group-flush">
                  <button
                    onClick={onClickMenu.bind(this, 'list')}
                    type="button"
                    className="list-group-item list-group-item-action"
                    aria-current="true"
                  >
                    用户列表
                  </button>
                </div>
              </div>
              <div className="col">{type.list && <RoleUserList />}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

const RoleUserList = () => {
  const { show } = useToast();
  const [currentItem, setCurrentItem] = useState<IRole>();
  const queryClient = useQueryClient();
  const context = useContext(RoleAdminContext);
  const [params, setParams] = useState<IQueryParams>({
    page: 0,
    size: 5,
  });
  const queryKey = ['/roles', context.updateUserItem?.id, '/users', params];

  const queryRoleUsersByIdQuery = useQuery(
    queryKey,
    async (context) => {
      return (await queryRoleUsersById({
        id: context.queryKey[1] + '',
        query: context.queryKey[3] as any,
      })) as IPagination<IRole>;
    },
    {
      keepPreviousData: true,
    },
  );

  const unAssignRoleMutation = useMutation(
    async (variables: TBody<IUnAssignRoleBody>) => {
      await unAssignRole(variables);
      await queryClient.invalidateQueries(queryKey);
    },
  );

  async function onClickRemove(item: IRole) {
    try {
      setCurrentItem(item);

      await unAssignRoleMutation.mutateAsync({
        id: context.updateUserItem?.id,
        data: {
          userId: item.id + '',
        },
      });

      show({
        type: 'SUCCESS',
        message: '删除完成',
      });
    } catch (e) {
      unAssignRoleMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickPrevious() {
    const data = queryRoleUsersByIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.max(0, data.pageable.page - 1);
    setParams({ ...params, page });
  }

  function onClickNext() {
    const data = queryRoleUsersByIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.min(data.pageable.pages, data.pageable.page + 1);
    setParams({ ...params, page });
  }

  if (queryRoleUsersByIdQuery.data) {
    const data = queryRoleUsersByIdQuery.data;

    return (
      <div className="row">
        <div className="col">
          <div className="vstack gap-4">
            <div className="row">
              <div className="col">
                <div className="table-responsive">
                  <table className="table table-hover align-middle">
                    <thead>
                      <tr className="text-nowrap">
                        <th scope="col" className="w-10 fw-normal">
                          ID
                        </th>
                        <th scope="col" className="w-10 fw-normal">
                          名称
                        </th>
                        <th scope="col" className="w-10"></th>
                      </tr>
                    </thead>
                    <tbody>
                      {data.content.map((item) => {
                        return (
                          <tr key={item.id} className="text-nowrap">
                            <td>{item.id}</td>
                            <td>{item.creatorAlias}</td>
                            <td>
                              <button
                                disabled={
                                  item.id === currentItem?.id &&
                                  unAssignRoleMutation.isLoading
                                }
                                onClick={onClickRemove.bind(this, item)}
                                className="btn btn-sm btn-danger"
                                type="button"
                              >
                                {item.id === currentItem?.id &&
                                unAssignRoleMutation.isLoading ? (
                                  <span
                                    className="spinner-border spinner-border-sm me-2"
                                    role="status"
                                    aria-hidden="true"
                                  ></span>
                                ) : (
                                  <i className="bi bi-trash me-2"></i>
                                )}
                                删除
                              </button>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </div>

                {data.content.length === 0 && (
                  <div className="text-muted">暂无角色用户</div>
                )}

                <div className="my-4">
                  <nav aria-label="用户分页">
                    <ul className="pagination justify-content-end">
                      <li className="page-item">
                        <a
                          onClick={onClickPrevious}
                          className="page-link cursor-pointer"
                        >
                          上一页
                        </a>
                      </li>
                      <li className="page-item">
                        <a
                          onClick={onClickNext}
                          className="page-link cursor-pointer"
                        >
                          下一页
                        </a>
                      </li>
                    </ul>
                  </nav>
                </div>
              </div>
            </div>

            <UserAddList queryKey={queryKey} />
          </div>
        </div>
      </div>
    );
  }

  if (queryRoleUsersByIdQuery.error) {
    return <Alert message={queryRoleUsersByIdQuery.error} type="error" />;
  }

  return <AlertLoad />;
};

const UserAddList = ({ queryKey }: { queryKey: QueryKey }) => {
  const { show } = useToast();
  const [params, setParams] = useState<IQueryParams>({
    page: 0,
    size: 5,
  });
  const [currentItem, setCurrentItem] = useState<IUser>();
  const context = useContext(RoleAdminContext);
  const queryClient = useQueryClient();

  const queryAllUserQuery = useQuery(
    ['/users', params],
    async (context) => {
      return (await queryAllUser({
        query: context.queryKey[1] as any,
      })) as IPagination<IUser>;
    },
    {
      keepPreviousData: true,
    },
  );

  const assignRoleMutation = useMutation(
    async (variables: TBody<IAssignRoleBody>) => {
      await assignRole(variables);
    },
  );

  async function onClickAdd(item: IUser) {
    try {
      setCurrentItem(item);

      await assignRoleMutation.mutateAsync({
        id: context.updateUserItem?.id,
        data: {
          userId: item.id + '',
        },
      });

      await queryClient.refetchQueries(queryKey, {}, { throwOnError: true });
      show({
        type: 'SUCCESS',
        message: '添加完成',
      });
    } catch (e) {
      assignRoleMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickPrevious() {
    const data = queryAllUserQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.max(0, data.pageable.page - 1);
    setParams({ ...params, page });
  }

  function onClickNext() {
    const data = queryAllUserQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.min(data.pageable.pages, data.pageable.page + 1);
    setParams({ ...params, page });
  }

  if (queryAllUserQuery.data) {
    const data = queryAllUserQuery.data;

    return (
      <div className="mt-4">
        <div className="table-responsive">
          <table className="table table-hover align-middle">
            <thead>
              <tr className="text-nowrap">
                <th scope="col" className="w-10 fw-normal">
                  ID
                </th>
                <th scope="col" className="w-10 fw-normal">
                  名称
                </th>
                <th scope="col" className="w-10"></th>
              </tr>
            </thead>
            <tbody>
              {data.content.map((item) => {
                return (
                  <tr key={item.id} className="text-nowrap">
                    <td>{item.id}</td>
                    <td>{item.creatorAlias}</td>
                    <td>
                      <button
                        disabled={
                          item.id === currentItem?.id &&
                          assignRoleMutation.isLoading
                        }
                        onClick={onClickAdd.bind(this, item)}
                        className="btn btn-sm btn-light"
                        type="button"
                      >
                        {item.id === currentItem?.id &&
                        assignRoleMutation.isLoading ? (
                          <span
                            className="spinner-border spinner-border-sm me-2"
                            role="status"
                            aria-hidden="true"
                          ></span>
                        ) : (
                          <i className="bi bi-plus-lg me-2"></i>
                        )}
                        添加
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>

          {data.content.length === 0 && (
            <div className="text-muted">暂无用户</div>
          )}

          <div className="my-4">
            <nav aria-label="用户分页">
              <ul className="pagination justify-content-end">
                <li className="page-item">
                  <a
                    onClick={onClickPrevious}
                    className="page-link cursor-pointer"
                  >
                    上一页
                  </a>
                </li>
                <li className="page-item">
                  <a onClick={onClickNext} className="page-link cursor-pointer">
                    下一页
                  </a>
                </li>
              </ul>
            </nav>
          </div>
        </div>
      </div>
    );
  }

  if (queryAllUserQuery.error) {
    return <Alert message={queryAllUserQuery.error} type="error" />;
  }

  return <AlertLoad />;
};
